import re
from django import template
from django.core.urlresolvers import reverse
from django.utils.http import urlquote
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from django.contrib.sites.models import Site
from django.contrib.auth.models import AnonymousUser, User
from djambe.wiki.models import Page, Tag
from djambe.wiki.utils import make_safe

register = template.Library()


def recent_changes(user, max_len):
  if user == '':
    user = AnonymousUser()
  page_list = []
  for page in Page.objects.order_by('-updated'):
    if page.is_viewable(user)[0]:
      page_list.append(page)
      if len(page_list) >= max_len:
        break
  return {
    'page_list': page_list,
  }

register.inclusion_tag('recent_changes.html')(recent_changes)


def tags():
  tags = Tag.objects.all().order_by('-count')
  return {
    'tags': tags,
  }

register.inclusion_tag('tags.html')(tags)


@register.simple_tag
def site_title():
  current_site = Site.objects.get_current()
  return current_site.name


@register.simple_tag
def url_encode(text):
  return urlquote(text)


'''
@register.simple_tag
def userid_to_username(num):
  try:
    user = User.objects.get(id=num)
    username = user.username
  except User.DoesNotExist:
    username = 'n/a'
  return username
'''


@register.simple_tag
def logout_path(request_path, get_dic):
  p = re.compile('/view/(.+)/$')
  m0 = p.search(request_path)
  if m0:
    try:
      r = Page.objects.get(title=m0.group(1))
      return request_path
    except Page.DoesNotExist:
      p = re.compile('^\d+$')
      m1 = p.match(m0.group(1))
      if m1:
        return request_path
      else:
        for i in Page.objects.all():
          return reverse('view', args=[i.id])
        return reverse('view', args=[1])
  p = re.compile('/search/$')
  m2 = p.search(request_path)
  if m2:
    return request_path + '?search_text=' + get_dic['search_text']
  else:
    return request_path


@register.simple_tag
def login_path(request_path, get_dic):
  p = re.compile('/search/$')
  m = p.search(request_path)
  if m:
    return request_path + '?search_text=' + get_dic['search_text']
  else:
    return request_path


@register.filter
def tag_join(list, autoescape=None):
  if autoescape:
    esc = conditional_escape
  else:
    esc = lambda x: x
  str = ''
  for tag in list:
    str += '<a href="' + reverse('tag', args=[tag.id]) + '">' + esc(tag.text) + '</a>, '
  pattern = re.compile(',\s$')
  return mark_safe(pattern.sub('', str))
tag_join.needs_autoescape = True


@register.filter
def highlight(text, regex_list, autoescape=None):
  if autoescape:
    esc = conditional_escape
  else:
    esc = lambda x: x
  p = re.compile('[\[\]\{\}\*#]+')
  t0 = p.sub('', text)
  p = re.compile('\s+')
  t = p.sub(' ', t0)

  margin = 100
  max_chunk_len = 240
  max_chunk_num = 5

  chunks = []

  l = 0
  r = 0
  # while True:
  for c in range(100):
    j = len(t)
    for regex in regex_list:
      j0 = regex.search(t[l:])
      if j0 is None:
        continue
      if j0.start() + l < j:
        j = j0.start() + l
        w0 = j0.end() + l
    if j == len(t):
      break

    l0 = max([0, j - margin])
    r0 = min([w0 + margin, len(t)])

    if r > l0:
      ch = chunks.pop()
      if r0 - ch[0] < max_chunk_len:
        chunks.append([ch[0], r0])
      else:
        chunks.append([ch[0], ch[1]])
        chunks.append([ch[1], r0])
    else:
      chunks.append([l0, r0])
    if len(chunks) >= max_chunk_num:
      break

    l = j + 1
    r = r0

  chunk_list = []
  for ch in chunks:
    s = t[ch[0]:ch[1]]
    chunk_list.append(s)
  out = '...'.join(chunk_list)

  if chunks:
    if chunks[0][0] != 0:
      out = '...' + out
    if chunks[-1][1] != len(t):
      out = out + '...'
  else:
    if len(t) > max_chunk_len:
      return mark_safe(make_safe(t[0:max_chunk_len]) + '...')
    else:
      return mark_safe(make_safe(t))

  for regex in regex_list:
    out = highlight_word(regex, out)
  return mark_safe(out)
highlight.needs_autoescape = True

def highlight_word(p, str):
  m = re.search(p, str)
  if m:
    return make_safe(str[0:m.start()]) + '<span style="background-color:yellow">' + make_safe(str[m.start():m.end()]) + '</span>' + highlight_word(p, str[m.end():])
  else:
    return str


@register.filter
def highlight_title(title, regex_list, autoescape=None):
  if autoescape:
    esc = conditional_escape
  else:
    esc = lambda x: x
  rwords = []
  for regex in regex_list:
    title = highlight_word(regex, title)
  return mark_safe(title)
highlight_title.needs_autoescape = True


@register.filter
def summary(text, autoescape=None):
  if autoescape:
    esc = conditional_escape
  else:
    esc = lambda x: x
  p = re.compile('[\[\]\{\}\*#]+')
  t = p.sub('', text)

  if len(t) > 100:
    return t[0:99] + '...'
  else:
    return t
